import 'dart:convert';
import 'package:flutter/widgets.dart';
import 'package:netease_cloud_music_api/utils/crypto.dart';
import 'package:netease_cloud_music_api/utils/player_request.dart';
import 'package:netease_cloud_music_api/utils/request.dart';
import 'package:netease_cloud_music_api/utils/utils.dart';
import 'package:shared_preferences/shared_preferences.dart';

mixin Login {
  /// 游客登录
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> anonimous() async {
    Map<String, dynamic> data = {'username': 'MGU1ZGU1MWNhMGNmOTc4M2VjZTkwYWI3YThmY2M4NDQgVzcxOE95Q1VfU3AxYmVJYUZZVG5jUT09'};
    return PlayerRequest(
      url: 'https://music.163.com/eapi/register/anonimous',
      data: data,
      options: PlayerRequestOptions(crypto: EncryptType.eapi, method: PlayerRequestMethod.post, ua: UserAgent.mobile, url: '/api/register/anonimous'),
    ).request();
  }

  /// 手机号码登录
  /// [phone] 手机号码, 必填
  /// [password] 密码, 必填
  /// [countryCode] 国家码，用于国外手机号登录, 默认为 86
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> cellphone({required int phone, required String password, int? countryCode}) async {
    if (!NeteaseCloudMusicApiUtils.hasMd5(md5String: password)) password = NeteaseCloudMusicApiUtils.generateMd5(data: password);
    final data = {'phone': phone, 'password': password, 'countrycode': countryCode ?? 86, 'rememberLogin': 'true'};
    PlayerRequestResponse response = await PlayerRequest(
      url: 'https://music.163.com/weapi/login/cellphone',
      data: data,
      options: PlayerRequestOptions(crypto: EncryptType.weapi, method: PlayerRequestMethod.post, ua: UserAgent.pc, cookie: 'os=pc'),
    ).request();
    if (response.status == 200) {
      return PlayerRequestResponse(status: response.status, body: {...jsonDecode(response.body), 'cookie': response.cookie}, cookie: response.cookie);
    } else
      return response;
  }

  /// 邮箱登录
  /// [username] 163 网易邮箱, 必填
  /// [password] 密码, 必填
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> login({required String username, required String password}) async {
    if (!NeteaseCloudMusicApiUtils.hasMd5(md5String: password)) password = NeteaseCloudMusicApiUtils.generateMd5(data: password);
    final data = {'username': username, 'password': password, 'rememberLogin': 'true'};
    PlayerRequestResponse response = await PlayerRequest(
            url: 'https://music.163.com/weapi/login',
            data: data,
            options: PlayerRequestOptions(crypto: EncryptType.weapi, ua: UserAgent.pc, cookie: 'os=pc', method: PlayerRequestMethod.post))
        .request();
    if (int.parse(jsonDecode(response.body)['code'].toString()) == 502) {
      return PlayerRequestResponse(status: 200, body: {'code': 502, 'message': '账号或密码错误'}, cookie: response.cookie);
    } else {
      return PlayerRequestResponse(status: 200, body: {...jsonDecode(response.body), 'cookie': response.cookie}, cookie: response.cookie);
    }
  }

  /// 登录状态
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> status() async {
    dynamic profile;
    dynamic bindings;
    Map<String, dynamic> retProfile = Map<String, dynamic>();
    PlayerRequestResponse response = await PlayerRequest(
      url: 'https://music.163.com',
      options: PlayerRequestOptions(
        method: PlayerRequestMethod.get,
      ),
    ).request();
    String body = response.body;
    RegExp regExpGUser = RegExp(r'GUser\s*=\s*([^;]+)');
    RegExp regExpGBinds = RegExp(r'GBinds\s*=\s*([^;]+)');
    Iterable<Match> matchesGUser = regExpGUser.allMatches(body);
    Iterable<Match> matchesGBinds = regExpGBinds.allMatches(body);

    if (matchesGUser.length > 0) {
      profile = matchesGUser.first.group(0)!.split(RegExp(r'GUser\s*='))[1];
    }
    if (matchesGBinds.length > 0) {
      bindings = matchesGBinds.first.group(0)!.split(RegExp(r'GBinds\s*='))[1];
    }

    String _profile = profile.toString();
    List _tempProfile = _profile.split('{');
    _profile = _tempProfile.last;
    _tempProfile = _profile.split('}');
    _profile = _tempProfile.first;
    _tempProfile = _profile.split(',');
    _tempProfile.forEach((element) {
      if (element is String) {
        List _temp = element.split(':');
        retProfile[_temp[0]] = _temp[1];
      }
    });

    if (profile == null || bindings == null) {
      return PlayerRequestResponse(status: 301, body: {'code': 301}, cookie: response.cookie);
    } else {
      return PlayerRequestResponse(status: 200, body: jsonEncode({'code': 200, 'profile': retProfile, 'bindings': jsonDecode(bindings)}), cookie: response.cookie);
    }
  }

  /// 刷新登录
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> refresh() {
    return PlayerRequest(
      url: 'https://music.163.com/weapi/login/token/refresh',
      options: PlayerRequestOptions(
        method: PlayerRequestMethod.post,
        crypto: EncryptType.weapi,
        ua: UserAgent.pc,
      ),
    ).request();
  }

  /// 检测手机号码是否已注册
  /// [phone] 手机号码, 必填
  /// [password] 密码, 必填
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> cellphoneExistenceCheck({required int phone, int? countryCode}) {
    return PlayerRequest(
      url: 'https://music.163.com/eapi/cellphone/existence/check',
      data: {'cellphone': phone, 'countrycode': countryCode ?? 86},
      options: PlayerRequestOptions(method: PlayerRequestMethod.post, crypto: EncryptType.eapi, url: '/api/cellphone/existence/check'),
    ).request();
  }

  /// 初始化名字
  /// [nickname] 名称
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> activateInitProfile({required String nickname}) {
    return PlayerRequest(
      url: 'https://music.163.com/eapi/activate/initProfile',
      data: {'nickname': nickname},
      options: PlayerRequestOptions(method: PlayerRequestMethod.post, crypto: EncryptType.eapi, url: '/api/activate/initProfile'),
    ).request();
  }

  /// 退出登录
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> logout() async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    PlayerRequestResponse playerRequestResponse = await PlayerRequest(
      url: 'https://music.163.com/weapi/logout',
      options: PlayerRequestOptions(
        method: PlayerRequestMethod.post,
        crypto: EncryptType.weapi,
        ua: UserAgent.pc,
      ),
    ).request();
    if (jsonDecode(playerRequestResponse.body)['code'] == 200) {
      sharedPreferences.setString('cookie', '{}');
      return playerRequestResponse;
    } else {
      Map<String, dynamic> body = jsonDecode(playerRequestResponse.body);
      return PlayerRequestResponse(
        status: playerRequestResponse.status,
        cookie: playerRequestResponse.cookie,
        body: {...body, 'message': '退出登录失败'},
      );
    }
  }
}
